package sc.senai.br.avaliacao;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Collection;

public final class CampeonatoImpl extends UnicastRemoteObject implements Campeonato {

    private final Collection<Jogador> jogadores;
    private final Juiz juiz;
    private final Comite comite;
    private final String registro;
    private static final int PORTA_RMI = 1099;
    private static final String SERVICO = "CampeonatoCambirela";
    private final String nome;
    public static final String NOME_PADRAO = "Campeonato Cambirela";

    public CampeonatoImpl(Comite comite, String nome) throws RemoteException {
        this.comite = comite;
        this.nome = (nome.trim().isEmpty() ? "Campeonato " : nome.trim());
        this.registro = this.comite.registra(this);
        System.out.println("---- Campeonato " + this.nome + " ----");
        Collection<Jogador> inscricoes = this.comite.getJogadores(this.registro);
        if (inscricoes.size() == 0) {
            do {
                System.out.println("Aguardando inscrições...");
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException ex) {
                    System.out.println("ERRO: Aguardou muito tempo para inscrições...");
                }
                inscricoes = this.comite.getJogadores(this.registro);
            } while (inscricoes.size() == 0);
        }
        this.jogadores = inscricoes;
        System.out.println("Nr Jogadores: " + this.jogadores.size());
        this.juiz = this.comite.getJuiz(this.registro);
        System.out.println("Juiz pronto!");
    }

    public String getNome() {
        return this.nome;
    }

    public void iniciarCampeonato() {
        int contador = 0;
        String vencedor = "";
        while (vencedor.isEmpty()) {
            contador++;
            RodadaImpl rodada = null;
            try {
                rodada = new RodadaImpl(this, this.juiz, contador);
            } catch (RemoteException ex) {
                System.out.println("ERRO: O campeonato ferrou! : " + ex);
                System.exit(1);
            }
            for (Jogador jogador : this.jogadores) {
                try {
                    jogador.novaRodada(rodada);
                } catch (RemoteException ex) {
                    System.out.println("ERRO: Um jogador passou mal!");
                    System.out.println("      " + ex);
                }
            }
            try {
                rodada.inicia();
            } catch (Exception ex) {
                System.out.println(String.format("ERRO: A rodada #%02d apresentou problemas para o inicio.", new Object[] { Integer.valueOf(contador) }));

                System.out.println("      " + ex);
            }
            while (!rodada.isFinalizada()) {
                try {
                    Thread.sleep(100L);
                } catch (InterruptedException ex) {
                    System.out.println("ERRO: Campeonato com problemas!");
                    System.out.println("      " + ex);
                }
            }
            try {
                System.out.println(String.format("Rodada #%02d: %s", new Object[] { Integer.valueOf(contador), rodada.getVencedor().isEmpty() ? "empate" : rodada.getVencedor() }));
            } catch (RemoteException ex) {
                System.out.println(String.format("ERRO: Problemas com a rodada #%02d.", new Object[] { Integer.valueOf(contador) }));
                System.out.println("     " + ex);
            }
            try {
                if (this.juiz.hasVencedorCampeonato()) {
                    vencedor = this.juiz.getVencedorCampeonato();
                }
            } catch (RemoteException ex) {
                System.out.println("ERRO: O juiz passou mal!");
                System.out.println("     " + ex);
            }
        }
        System.out.println("Vencedor do campeonato:" + vencedor);
        for (Jogador jogador : this.jogadores) {
            try {
                jogador.finalCampeonato(this.nome, vencedor);
            } catch (RemoteException ex) {
                System.out.println("ERRO: Um jogador passou mal!");
                System.out.println("      " + ex);
            }
        }
    }
}